/**
 * 
 */
package co.fitstart.tencent.customer.accessor.impl;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.http.annotation.Rao;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.wechat.entity.cfg.Config;
import com.demo2do.core.wechat.entity.token.JsTicket;
import com.demo2do.core.wechat.entity.token.Token;
import com.demo2do.core.wechat.rao.wechat.WechatTokenRao;
import com.demo2do.core.wechat.utils.WechatUtils;

import co.fitstart.tencent.customer.accessor.WechatTokenAccessor;
import co.fitstart.tencent.customer.rao.WechatInvoiceRao;

/**
 * @author downpour
 *
 */
@Component("wechatTokenAccessor")
public class WechatTokenAccessorImpl implements WechatTokenAccessor {
    
    private static final Logger logger = LoggerFactory.getLogger(WechatTokenAccessorImpl.class);
    
    @Rao
    private WechatTokenRao wechatTokenRao;
    
    @Rao
    private WechatInvoiceRao invoiceRao;
    
    private Config config;
    
    /**
     * 
     * @param appid
     * @param appsecret
     */
    @Autowired
    public void config(@Value("#{wechat['appid']}") String appid, @Value("#{wechat['appsecret']}") String appsecret) {
        this.config = new Config(appid, appsecret);
    }

    /* (non-Javadoc)
     * @see com.edoomath.tencent.accessor.WechatTokenAccessor#requestAccessToken()
     */
    public Token requestAccessToken() {
        
        logger.trace("#requestAccessToken - Request global access_token for appid[{}] and appsecret[{}]", this.config.getAppid(), this.config.getAppsecret());
        
        // 1. call rao to get access token
        HttpResult httpResult = wechatTokenRao.getAccessToken(config.getAppid(), config.getAppsecret());
        
        if(WechatUtils.isValid(httpResult)) {  // this is a valid response
            
            // 2. get response data
            Map<String, Object> response = httpResult.describe();
            
            String accessToken = (String) response.get("access_token");
            Integer expireTime = (Integer) response.get("expires_in");
            
            return new Token(accessToken, expireTime);
        
        }
        
        throw WechatUtils.toBusinessException(httpResult);
    }

    /* (non-Javadoc)
     * @see com.edoomath.tencent.accessor.WechatTokenAccessor#requestJsTicket()
     */
    public JsTicket requestJsTicket() {
        
        // 1. get global access_token
        String accessToken = this.requestAccessToken().getAccessToken();  // an internal call will always return correct access_token
        
        logger.trace("#requestJsTicket - Start get js ticket with accessToken[{}]", accessToken);
        
        // 2. call rao to get js_ticket
        HttpResult httpResult = wechatTokenRao.getJsTicket(accessToken, "jsapi");

        if(WechatUtils.isValid(httpResult)) {  // this is a valid response, let's return ticket
            
            Map<String, Object> response = httpResult.describe();
            
            // get ticket from response
            String ticket = (String) response.get("ticket");
            Integer expireTime = (Integer) response.get("expires_in");
            
            return new JsTicket(this.config.getAppid(), ticket, expireTime);
        
        }
        
        logger.trace("#requestJsTicket - get js ticket result[{}], responseText[{}]", JsonUtils.toJson(httpResult), httpResult.getResponseText());
        
        throw WechatUtils.toBusinessException(httpResult); 
        
        
    }
	
}
